package com.yunji.cabinet.context.calculate;

import com.yunji.cabinet.bo.CapacityCeilingBO;
import com.yunji.cabinet.bo.CapacityQuantityBO;
import com.yunji.cabinet.cache.CabinetCache;
import com.yunji.cabinet.device.DeviceInfoCache;
import com.yunji.cabinet.domain.ContainerCell;
import com.yunji.cabinet.enums.CellStatus;
import com.yunji.cabinet.enums.LackStatus;
import com.yunji.common.model.cache.CabinetCacheDTO;
import com.yunji.common.model.cache.ContainerTypeCacheDTO;
import com.yunji.common.model.cache.ProductCacheDTO;
import com.yunji.common.utils.ConvertDataUtil;
import com.yunji.common.utils.DecimalUtils;
import com.yunji.coffee.entity.dto.DeviceCellDetailDTO;
import com.yunji.coffee.entity.dto.DeviceInfoDTO;
import com.yunji.coffee.entity.dto.ICommonDeviceDetail;
import com.yunji.product.cache.ProductCache;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class CabinetCalculate {

    public static BigDecimal getProductHeight(Long productId) {
        ProductCacheDTO product = ProductCache.getProduct(productId);
        return product.getProductHeight();
    }

    public static BigDecimal getCapacityCeiling(CapacityCeilingBO bo) {
        ContainerTypeCacheDTO containerType = CabinetCache.getContainerType(bo.getTypeCode());
        BigDecimal typeHeight = containerType.getTypeHeight();
        Long productId = bo.getProductId();
        return getQuantityByHeightDecimal(CapacityQuantityBO.builder().distance(typeHeight.intValue()).productId(productId).build());
    }

    public static Integer getCabinetCellStatus(Integer productNums) {
        if (productNums > 0) {
            return CellStatus.ENABLE.getCode();
        }
        return CellStatus.UNABLE.getCode();
    }

    public static Integer getLackStatus(Integer productNums) {
        if (productNums >= 5) {
            return LackStatus.NO.getCode();
        }
        return LackStatus.YES.getCode();
    }

    public static BigDecimal getQuantityByHeightDecimal(CapacityQuantityBO bo) {
        BigDecimal distance = BigDecimal.valueOf(bo.getDistance());
        Long productId = bo.getProductId();
        BigDecimal productHeight = getProductHeight(productId);
        return DecimalUtils.getInteger(distance).divide(productHeight, 0, RoundingMode.DOWN);
    }

    public static DeviceCellDetailDTO getEventQuantity(String imei, Integer distance, Integer ordinal) {
        CabinetCacheDTO cabinet = CabinetCache.getCabinet(imei);
        List<ContainerCell> cellList = CabinetCache.getCellList(cabinet.getContainerId());
        ContainerCell cell = cellList.stream().filter(a -> a.getOrdinal().equals(ordinal)).findFirst().orElse(null);
        if (cell == null) return new DeviceCellDetailDTO();
        return getEventQuantity(cabinet, cell, distance);
    }

    public static DeviceCellDetailDTO getEventQuantity(CabinetCacheDTO cabinet, ContainerCell cell, Integer distance) {
        return new DeviceCellDetailDTO(cell.getOrdinal(), cell.getProductId(),
                getQuantityByHeightDecimal(CapacityQuantityBO.builder().
                        distance(cabinet.getTypeHeight().intValue() - distance).productId(cell.getProductId()).build()).intValue());
    }

    public static Map<Integer, DeviceCellDetailDTO> getNumMap(String imei) {
        DeviceInfoDTO info = DeviceInfoCache.getInfo(imei);
        if (info == null) return Collections.emptyMap();
        return ConvertDataUtil.list2KeyValueMap(info.getDetailList(),
                ICommonDeviceDetail::getOrdinal, ICommonDeviceDetail::getCellDetail);
    }
}
